import React, { useEffect, useState } from "react";

import { Card, Select, Input, Button, Table } from "antd";
import PlusCircleOutlined from "@ant-design/icons/lib/icons/PlusCircleOutlined";
import MyButton from "../../components/MyButton";
import { reqProduct, reqSearchProduct } from "../../api";
import { PAGE_SIZE } from "../../utils/constants";
import { useNavigate } from "react-router-dom";
const { Option } = Select;

// product的默认子路由
const ProductHome: React.FC = () => {
  // useNavigate()实现编程式导航
  const navigate = useNavigate();
  // 商品的数组 用作表格的数据源
  const [product, setproduct] = useState([]);
  // 商品的总数量(主要用于分页)也是从后台请求来的
  const [total, settotal] = useState(0);
  // 是否正在加载
  const [loading, setloading] = useState(false);
  // 搜索条件input的关键字
  const [searchName, setsearchName] = useState("");
  // 根据什么方式搜索 名称字段还是描述 默认按照名字搜索
  const [searchType, setsearchType] = useState("productName");
  // 保存当前pageNum
  const [pageN, setpageN] = useState<any>();

  useEffect(() => {
    // 页面第一次加载渲染的时候就请求后端的数据显示table
    getProduct(1, 5);
    //在使用useEffect时，当我们将函数的声明放在useEffect函数外面时或者使用useState定义的历史变量,会报eslint警告 一般我们会选择忽视这个警告
    // 如果不选择忽视这个警告  可以选择把函数的声明也拉到useeffect内部
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 获取指定页码的列表数据显示
  const getProduct = async (pageNum: number, pageSize: number) => {
    // 保存当前pageNUm
    setpageN(pageNum);
    // 显示loading效果
    setloading(true);
    // 如果搜索关键字存在  说明要进行搜索分页数据获取  不然就是一般分页数据获取
    let result;
    // 根据是否存在关键字确定获取的数据是全部数据还是按照关键字搜索数据
    if (searchName) {
      // 如果有关键字就按照关键字搜索
      result = await reqSearchProduct(
        searchType,
        pageNum,
        pageSize,
        searchName
      );
    } else {
      // 没有关键字就获取全部的分页数据
      result = await reqProduct(pageNum, pageSize);
    }
    // 把请求结果中我们需要的data解构出来
    const { data: res } = result;
    // 隐藏loading效果
    setloading(false);
    if (res.status === 0) {
      // 把数据中total, list解构出来
      const { total, list } = res.data;
      setproduct(list);
      settotal(total);
    }
  };
  // table组件的title部分 有搜索框以及搜索条件的选择以及按钮
  const title = (
    <span>
      <Select
        value={searchType}
        // Select选择发生改变的时候触发onchange函数 参数是option的val
        onChange={(val) => {
          // 根据下拉的值选择的改变设置searchType的值
          setsearchType(val);
        }}
        style={{ width: 150 }}
      >
        <Option value="productName">按照名称搜索</Option>
        <Option value="productDesc">按照描述搜索</Option>
      </Select>
      <Input
        value={searchName}
        placeholder="请输入关键字"
        style={{ width: 250, margin: "0 20px" }}
        onChange={(e) => {
          // Input的onchange参数是e,是事件的e
          setsearchName(e.target.value);
        }}
      ></Input>
      <Button
        type="primary"
        onClick={() => {
          // 同样使用getProduct方法  修改这个方法可以让他实现获取全部数据和按条件搜索两种情况
          getProduct(1, PAGE_SIZE);
        }}
      >
        搜索
      </Button>
    </span>
  );

  // table组件的extra部分 在table组件右上角 显示添加商品的一个按钮
  const extra = (
    <span>
      <Button
        type="primary"
        onClick={() => {
          // 编程式导航 通过useNavigate进行路由的跳转 跳转到update 也就是add-update组件
          navigate("/admin/product/update");
        }}
      >
        添加商品
        <PlusCircleOutlined />
      </Button>
    </span>
  );

  // columns是规定表格列的约束
  const columns = [
    {
      title: "商品名称",
      dataIndex: "name",
      key: "name",
    },
    {
      title: "商品描述",
      dataIndex: "desc",
      key: "desc",
    },
    {
      title: "价格",
      dataIndex: "price",
      key: "price",
      width: 120,
      // 给价格添加一个人民币符号
      // render可以自定义渲染成什么样子 三个参数分别对应当前行的自己的一些数据
      // 生成复杂数据的渲染函数，三个参数分别为当前行的值，当前行数据，行索引
      render: (text: any, record: any, index: any) => "¥" + text,
    },
    {
      title: "状态",
      dataIndex: "status",
      key: "status",
      width: 100,
      render: (status: any) => {
        // 后台数据中的status有的是字符有的是数字，在判断的时候统一转为数字去比较
        if (Number(status) === 1) {
          return (
            <span>
              {/* 根据数据得到的status(这里作为参数和数据源名字都是status)来判断渲染什么样子的按钮和文字内容 */}
              <Button type="primary">下架</Button>
              <span>在售</span>
            </span>
          );
        } else if (status === 0) {
          return (
            <span>
              <Button type="primary">上架</Button>
              <span>已下架</span>
            </span>
          );
        }
      },
    },
    {
      title: "操作",
      dataIndex: "action",
      key: "action",
      width: 100,
      render: (text: any, record: any, index: any) => {
        // 渲染两个可以点击的文字 用作修改和显示详情页 具体回调函数还需要往MyButton组件上绑定
        return (
          <span>
            <MyButton
              placeHolder="详情"
              onClick={() => {
                // 编程式导航 通过useNavigate进行路由的跳转  // navigate(-1)表示goback  navigate(1)表示前进
                // 页面跳转的时候携带参数 写法如下 { state: { data: record } } record为参数
                navigate("/admin/product/detail", { state: { data: record } });
              }}
            ></MyButton>
            <MyButton
              placeHolder="修改"
              onClick={() => {
                // 编程式导航 通过useNavigate进行路由的跳转  // navigate(-1)表示goback  navigate(1)表示前进
                // 页面跳转的时候携带参数 写法如下 { state: { data: record } } record为参数
                navigate("/admin/product/update", { state: { data: record } });
              }}
            ></MyButton>
          </span>
        );
      },
    },
  ];

  return (
    <Card title={title} extra={extra}>
      <Table
        //dataSource是Table的显示数据源
        dataSource={product}
        // columns是Table的列控制
        columns={columns}
        // 为table中的每一项设置一个独立不重复的id 这里用的是mongodb中的_id 每次请求过来的数据都有这个_id 不写会有警告
        rowKey="_id"
        // 是否有边框
        bordered
        // 是否显示loading效果
        loading={loading}
        // 分页设置
        pagination={{
          //配置分页项相关 包括每页几项 是否可以快速跳转 table总数多少等等
          current: pageN,
          defaultPageSize: PAGE_SIZE,
          showQuickJumper: true,
          total: total,
          // onchange会在切换页码的时候触发
          onChange: (page) => {
            // page就是这个onChange函数触发的是 切换到的第几个页码
            // 重新请求后台相关数据
            getProduct(page, PAGE_SIZE);
          },
        }}
      ></Table>
    </Card>
  );
};

export default ProductHome;

// 视频 P63
